import time
import cplex
import cplex.callbacks as CPX_CB
import random
import numpy as np
from ccfs.instances import genfs
from ccfs.callbacks import CheckBounds

def bench_checkresolve(NI = 40, NS=35):
    step = 0.1
    flag = [0] #mutable
    I = range(NI)
    S = range(NS)
    x_name = ["x" + '_' + str(i) for i in I]
    v_name = ["v" + '_' + str(i) for i in I]
    y_name = ["y" + "_" + str(s) for s in S]
    vb_name = ["vb"+str(i) for i in I]

    c = genfs(NI, NS)
    c.parameters.read_file('../../param/stofac.prm')
    c.solve()
    true_obj_val = c.solution.get_objective_value()

    # Set initial bounds for v
    v_lb = [15]*NI
    #v_lb = [true_v_sol[i] + 0.1 for i in I]
    v_chgind = [0]*NI
    c.variables.set_lower_bounds(zip(v_name, v_lb))

    # Pass references to the callback function
    cbinstance  = c.register_callback(CheckBounds)
    cbinstance.times_called = 0
    cbinstance.v_lb = v_lb
    cbinstance.x_name = x_name
    cbinstance.v_name = v_name
    cbinstance.y_name = y_name
    cbinstance.vb_name = vb_name
    cbinstance.flag = flag
    cbinstance.NI = NI
    cbinstance.NS = NS
    cbinstance.I = I
    cbinstance.S = S
    iter = 0

    # Start the loop
    while(iter < 200):
        iter += 1

        # resolve the problem
        c.solve()
        if flag[0] == 1: #pass all the test
            break
        elif flag[0] == 0: #binding being checked
            # decreate the lower bound for v
            c.variables.set_lower_bounds(zip(v_name, v_lb))
        else: # at the root node integer solution is found
            v_lb = [v_lb[i] - step for i in I]
            c.variables.set_lower_bounds(zip(v_name, v_lb))
    my_obj_val = c.solution.get_objective_value()
    return true_obj_val, my_obj_val

f = open('bench_checkresolve.res', 'w')
for ni in range(10, 20, 2):
    for ns in range(10, 20, 2):
        to, mo = bench_checkresolve(ni, ns)
        f.write(str(ni)+' '+str(ns)+' '+str(to)+' '+str(mo)+'\n')
